﻿#include "mainwnd.h"
#include <QVariant>
#include <QGraphicsDropShadowEffect>
#include <QVBoxLayout>
#include <QtWidgets>
#include <QPixmap>
#include "tools.h"
#include "sysprotect.h"
#include "kidsprotect.h"
#include "virscan.h"
#include "utils.h"

#if _MSC_VER >= 1600
#pragma execution_character_set("utf-8")
#endif


MainWnd::MainWnd(QWidget *parent)
    : QDialog(parent)
{
    m_pMianPane = new MainPane(this);

#ifdef Q_OS_WIN32
    setWindowFlags(windowFlags() | (Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint));
#else
    setWindowFlags(windowFlags() | (Qt::FramelessWindowHint));
#endif // Q_OS_WIN32

    setProperty("canMove", true);
    setAttribute(Qt::WA_TranslucentBackground, true);
    setWindowTitle("火绒安全软件");

    QVBoxLayout *mainLayout = new QVBoxLayout(this);
    mainLayout->addWidget(m_pMianPane);
    mainLayout->setMargin(5);
    setLayout(mainLayout);
}

MainWnd::~MainWnd()
{

}

void MainWnd::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    QPainterPath path;
    path.setFillRule(Qt::WindingFill);
    path.addRect(9, 9, this->width()-18, this->height()-18);
    painter.setRenderHint(QPainter::Antialiasing, true);
    painter.fillPath(path, QBrush(Qt::white));
    QColor color(0, 0, 0, 50);
    for(int i=0; i<9; i++)
    {
        QPainterPath path;
        path.setFillRule(Qt::WindingFill);
        path.addRect(9-i, 9-i, this->width()-(9-i)*2, this->height()-(9-i)*2);
        color.setAlpha(150 - qSqrt(i)*50);
        painter.setPen(color);
        painter.drawPath(path);
    }
}

MainPane::MainPane(QWidget *parent)
{
    m_pTopTools = new QWidget(this);
    m_pCenter = new QWidget(this);
    m_pBottom = new QWidget(this);
    m_pVirusKill = new QWidget(this);
    m_pTools = new Tools(this);
    m_pVirscan = new Virscan(this);
    m_pSysProtect = new SysProtect(this);
    m_pKidsProtect = new KidsProtect(this);
    m_pixFlash = new QPixmap(":/img/100/ani_flash.png");
    m_bShowChild = false;

    setAttribute(Qt::WA_StyledBackground);  // 禁止父窗口样式影响子控件样式
    setFixedSize(820, 540);

    setStyleSheet("MainPane{"
                  "background: #fff;"
                  "background-image: url(:/img/100/bk_main_normal.png);"
                  "background-repeat: no-repeat}");

    m_pTools->hide();
    m_pSysProtect->hide();
    m_pKidsProtect->hide();
    m_pVirscan->hide();

    InitCtrl();
}

MainPane::~MainPane()
{

}

void MainPane::InitCtrl()
{
    QVBoxLayout *mainLayout = new QVBoxLayout(this);
    mainLayout->addWidget(m_pTopTools);
    mainLayout->addWidget(m_pCenter);
    mainLayout->addWidget(m_pBottom);
    mainLayout->setMargin(7);
    mainLayout->setSpacing(0);
    setLayout(mainLayout);

    InitTop();
    InitCenter();
    InitBottom();
    InitVirusKill();
}

void MainPane::InitTop()
{
    m_pTopTools->setFixedHeight(24);
    m_pTopTools->setObjectName("m_pTopTools");
    m_pTopTools->setStyleSheet("QWidget#m_pTopTools{"
                  "background-image: url(:/img/100/logo_gold.png);"
                  "background-repeat: no-repeat}");

    QHBoxLayout *mainLayout = new QHBoxLayout(m_pTopTools);
    mainLayout->setMargin(0);
    mainLayout->setSpacing(0);
    mainLayout->addStretch(1);
    m_btnBack = CreateMiniBtn("返回", ":/img/100/back.png");
    connect(m_btnBack, &QPushButton::clicked, [=]() {
       HideChild();
    });

    mainLayout->addWidget(m_btnBack);
    mainLayout->addWidget(CreateMiniBtn("菜单", ":/img/100/menu_gray.png", QSize(36, 24), [=]()
                            {
                              //创建菜单对象
                              QMenu *pMenu = new QMenu();
                              pMenu->setStyleSheet(
                                            "QMenu {background-color : #ffffff; padding:0px; border-radius:15px;}"
                                            "QMenu::item {font-size:12px; color:#444444; background-color: #ffffff; padding: 4px 40px 5px 30px; margin: 0px;}"
                                            "QMenu::item:selected  { background: #ffa924; }"
                                            "QMenu::separator{ height: 0px; }"
                                            "QMenu::icon { margin-left: 20px; width:18px; height: 18px; }");
                              QAction *pCollect = CreateAction(tr("安全设置"), pMenu, ":/img/100/menu_sys_cfg/config.png");
                              QAction *pMsgMgr = CreateAction(tr("安全日志"), pMenu, ":/img/100/menu_sys_cfg/log.png");
                              QAction *pInvite = CreateAction(tr("隔离区"), pMenu, ":/img/100/menu_sys_cfg/isolation.png");
                              QAction *pSign1 = CreateAction(tr("信任区"), pMenu, ":/img/100/menu_sys_cfg/trust.png");
                              QAction *pSign2 = CreateAction(tr("检查更新"), pMenu, ":/img/100/menu_sys_cfg/update.png");
                              QAction *pSign3 = CreateAction(tr("问题反馈"), pMenu, ":/img/100/menu_sys_cfg/feedback.png");
                              QAction *pSign4 = CreateAction(tr("病毒上报"), pMenu, ":/img/100/menu_sys_cfg/help.png");

                              QAction *pRest = CreateAction(tr("简体中文"), pMenu, ":/img/100/menu_sys_cfg/zh_cn.png");
                              QAction *pGoOffwork = CreateAction(tr("繁體中文"), pMenu, ":/img/100/menu_sys_cfg/zh_tw.png");
                              QAction *pEn = CreateAction(tr("English"), pMenu, ":/img/100/menu_sys_cfg/en.png");

                              QMenu *pChildRest = new QMenu(pMenu);
                              pChildRest->setTitle(tr("语言设置"));
                              pChildRest->addAction(pRest);
                              pChildRest->addAction(pGoOffwork);
                              pChildRest->addAction(pEn);

                              QAction *pAbout = CreateAction(tr("关于我们"), pMenu, ":/img/100/menu_sys_cfg/about.png");

                              //把QAction对象添加到菜单上
                              pMenu->addAction(pCollect);
                              pMenu->addAction(pMsgMgr);
                              pMenu->addAction(pInvite);
                              pMenu->addAction(pSign1);
                              pMenu->addAction(pSign2);
                              pMenu->addAction(pSign3);
                              pMenu->addAction(pSign4);
                              QAction *pLang = pMenu->addMenu(pChildRest);
                              pLang->setIcon(QIcon(QPixmap(":/img/100/menu_sys_cfg/language.png").copy(0, 0, 18, 18)));
                              pMenu->addAction(pAbout);

                              pMenu->exec(cursor().pos());

                              //释放内存
                              QList<QAction*> list = pMenu->actions();
                              foreach (QAction* pAction, list)
                                  delete pAction;

                              delete pMenu;
                          }));

    mainLayout->addWidget(CreateMiniBtn("最小化", ":/img/100/min_gray.png", QSize(36, 24), [=]() {
       parentWidget()->setWindowState(Qt::WindowMinimized);
    }));
    mainLayout->addWidget(CreateMiniBtn("关闭", ":/img/100/close_gray.png", QSize(36, 24), [=]() {
        qApp->quit();
    }));
    m_btnBack->hide();
}

void MainPane::InitCenter()
{
    QLabel *mianLab = new QLabel("火绒正在保护您的电脑", this);
    mianLab->setObjectName("mianLab");
    mianLab->setAlignment(Qt::AlignCenter);
    mianLab->setStyleSheet("font-size: 22px; font-weight: 500; color: #85724b");

    QLabel *mianLogo = new QLabel(this);
    mianLogo->setObjectName("mianLogo");
    mianLogo->setFixedSize(200, 220);
    mianLogo->setStyleSheet("background-image: url(:/img/100/icon_main_normal.png);"
                  "background-repeat: no-repeat");

    QLabel *labelTip1 = new QLabel(this);
    labelTip1->setAlignment(Qt::AlignRight);
    labelTip1->setText("<p style=\"color:#444444;font-size:15px;\"> 已保护 <span style=\"color:#ffa924;font-size:24px;\">100</span> 天</p>");

    QLabel *labelTip2 = new QLabel("版本: 5.0.73.1 病毒库: 2023-1-18 14:09", this);
    labelTip2->setAlignment(Qt::AlignRight);
    labelTip2->setStyleSheet("font-size: 12px; font-weight: 400; color: #444444");

    QVBoxLayout *tipLayout = new QVBoxLayout();
    tipLayout->setContentsMargins(0, 0, 0, 70);
    tipLayout->setSpacing(10);
    tipLayout->addStretch();
    tipLayout->addWidget(labelTip1);
    tipLayout->addWidget(labelTip2);


    QHBoxLayout *centerLayout = new QHBoxLayout();
    centerLayout->setMargin(0);
    centerLayout->setSpacing(0);
    centerLayout->addStretch(1);
    centerLayout->addWidget(mianLogo);
    centerLayout->addLayout(tipLayout, 1);


    QVBoxLayout *mainLayout = new QVBoxLayout(m_pCenter);
    mainLayout->setContentsMargins(0, 60, 0, 0);
    mainLayout->setSpacing(0);
    mainLayout->addWidget(mianLab);
    mainLayout->addLayout(centerLayout);


    setProperty("rotate", 0);
    QPropertyAnimation *animation1 = new QPropertyAnimation(this, "rotate");
    animation1->setDuration(3000);
    animation1->setStartValue(-1);
    animation1->setEndValue(35);
    //connect(animation1, SIGNAL(valueChanged(const QVariant &)), this, SLOT(update()));
    connect(animation1, &QPropertyAnimation::valueChanged, [=](const QVariant &v)
    {
        QSize sizeImg(470, 320);
        QPoint topleft((width() - 470) / 2, 0);
        QRect rcImg(topleft, sizeImg);
        update(rcImg);
    });

    QPropertyAnimation *animation2 = new QPropertyAnimation(this, "rotate");
    animation2->setDuration(2000);
    animation2->setStartValue(-1);
    animation2->setEndValue(-1);

    QSequentialAnimationGroup *paraGroup = new QSequentialAnimationGroup(this);
    paraGroup->addAnimation(animation1);
    paraGroup->addAnimation(animation2);
    paraGroup->setLoopCount(-1);
    paraGroup->start();
}

void MainPane::InitBottom()
{
    m_pBottom->setFixedHeight(150);

    QHBoxLayout *mainLayout = new QHBoxLayout(m_pBottom);
    mainLayout->setContentsMargins(0, 0, 0, 50);
    mainLayout->setSpacing(110);
    mainLayout->addStretch();

    QPushButton *btn = CreateBtn("病毒查杀", ":/img/100/virscan.png");
    connect(btn, &QPushButton::clicked, [=]() {
       ShowVirusKill();
    });
    mainLayout->addWidget(btn);

    QPushButton *btnSysProtect = CreateBtn("防护中心", ":/img/100/sysprotect.png");
    mainLayout->addWidget(btnSysProtect);
    connect(btnSysProtect, &QPushButton::clicked, [=]() {
       ShowChild(m_pSysProtect);
    });

    QPushButton *btnKidsProtect = CreateBtn("访问控制", ":/img/100/kidsprotect.png");
    mainLayout->addWidget(btnKidsProtect);
    connect(btnKidsProtect, &QPushButton::clicked, [=]() {
       ShowChild(m_pKidsProtect);
    });

    QPushButton *btnTools = CreateBtn("安全工具", ":/img/100/tools.png");
    mainLayout->addWidget(btnTools);
    connect(btnTools, &QPushButton::clicked, [=]() {
       ShowChild(m_pTools);
    });
    mainLayout->addStretch();
}

void MainPane::InitVirusKill()
{
    m_pVirusKill->hide();
    m_pVirusKill->setFixedHeight(180);
    m_pVirusKill->setObjectName("m_pVirusKill");
    m_pVirusKill->setStyleSheet("QWidget#m_pVirusKill{background: #fff; background-image: url(:/img/100/viruscan/expand_bk.png); background-repeat: no-repeat; background-position: bottom}");

    QHBoxLayout *mainLayout1 = new QHBoxLayout();
    mainLayout1->setContentsMargins(0, 0, 0, 0);
    mainLayout1->setSpacing(110);
    mainLayout1->addStretch(1);
    QPushButton *btnAll = CreateBtn("全盘查杀", ":/img/100/viruscan/all.png");
    mainLayout1->addWidget(btnAll);
    connect(btnAll, &QPushButton::clicked, [=]() {
       ShowChild(m_pVirscan);
       HideVirusKill();
    });
    QPushButton *btnQuick = CreateBtn("快速查杀", ":/img/100/viruscan/quick.png");
    mainLayout1->addWidget(btnQuick);
    connect(btnQuick, &QPushButton::clicked, [=]() {
       ShowChild(m_pVirscan);
       HideVirusKill();
    });
    mainLayout1->addWidget(CreateBtn("自定义查杀", ":/img/100/viruscan/custom.png"));
    mainLayout1->addStretch(1);

    QHBoxLayout *mainLayout2 = new QHBoxLayout();
    mainLayout2->setContentsMargins(0, 0, 0, 0);
    mainLayout2->addStretch(1);
    QPushButton *btn = CreateMiniBtn("", ":/img/100/viruscan/expand.png", QSize(28, 28));
    connect(btn, &QPushButton::clicked, [=]() {
       HideVirusKill();
    });
    mainLayout2->addWidget(btn);
    mainLayout2->addStretch(1);

    QVBoxLayout *mainLayout = new QVBoxLayout(m_pVirusKill);
    mainLayout->setSpacing(0);
    mainLayout->setContentsMargins(0, 0, 0, 0);
    mainLayout->addLayout(mainLayout1);
    mainLayout->addStretch(1);
    mainLayout->addLayout(mainLayout2);
}

void MainPane::UpdateCtrlState()
{
    //移除原有样式
    style()->unpolish(this);
    //必须要有下面这行不然还是不会卸载
    this->setStyleSheet("");

    if (m_bShowChild)
    {
        setStyleSheet("MainPane{background: #f8f9f9;}");
        m_btnBack->show();
    }
    else
    {
        setStyleSheet("MainPane{"
                      "background: #fff;"
                      "background-image: url(:/img/100/bk_main_normal.png);"
                      "background-repeat: no-repeat}");
        m_btnBack->hide();
    }

    //重新设置新的该控件的样式。
    style()->polish(this);

    update();
}

void MainPane::ShowVirusKill()
{
    m_pVirusKill->show();

    QPoint point(0, height() - m_pVirusKill->height());
    QPoint point2(0, height());
    QRect rcStart, rcEnd;
    rcEnd = QRect(point, QSize(width(), m_pVirusKill->height()));
    rcStart = QRect(point2, QSize(width(), m_pVirusKill->height()));

    QPropertyAnimation *animation = new QPropertyAnimation(m_pVirusKill, "geometry");
    animation->setDuration(180);
    animation->setStartValue(rcStart);
    animation->setEndValue(rcEnd);
    animation->start(QAbstractAnimation::DeleteWhenStopped);

    UpdateCtrlState();
}

void MainPane::HideVirusKill()
{
    QPoint point(0, height() - m_pVirusKill->height());
    QPoint point2(0, height());
    QRect rcStart, rcEnd;
    rcStart = QRect(point, QSize(width(), m_pVirusKill->height()));
    rcEnd = QRect(point2, QSize(width(), m_pVirusKill->height()));

    QPropertyAnimation *animation = new QPropertyAnimation(m_pVirusKill, "geometry");
    connect(animation, &QPropertyAnimation::finished, [=]() {
       m_pVirusKill->hide();
    });
    animation->setDuration(180);
    animation->setStartValue(rcStart);
    animation->setEndValue(rcEnd);
    animation->start(QAbstractAnimation::DeleteWhenStopped);
}

void MainPane::ShowTools()
{
    m_pTools->show();

    QPoint point(0, 40);
    QPoint point2(0, height());
    QRect rcStart, rcEnd;
    rcEnd = QRect(point, QSize(width(), height() - 40));
    rcStart = QRect(point2, QSize(width(), 0));

    QPropertyAnimation *animation = new QPropertyAnimation(m_pTools, "geometry");
    animation->setDuration(180);
    animation->setStartValue(rcStart);
    animation->setEndValue(rcEnd);
    animation->start(QAbstractAnimation::DeleteWhenStopped);

    m_bShowChild = true;
    UpdateCtrlState();
}

void MainPane::HideTools()
{
    QPoint point(0, 40);
    QPoint point2(0, height());
    QRect rcStart, rcEnd;
    rcStart = QRect(point, QSize(width(), height() - 40));
    rcEnd = QRect(point2, QSize(width(), 0));

    QPropertyAnimation *animation = new QPropertyAnimation(m_pTools, "geometry");
    connect(animation, &QPropertyAnimation::finished, [=]() {
       m_pTools->hide();
    });
    animation->setDuration(180);
    animation->setStartValue(rcStart);
    animation->setEndValue(rcEnd);
    animation->start(QAbstractAnimation::DeleteWhenStopped);

    m_bShowChild = false;
    UpdateCtrlState();
}

void MainPane::ShowChild(QWidget *child)
{
    child->show();
    child->raise();

    {
        BaseChildPane *child = GetChild();
        child->OpenPage();
    }

    QParallelAnimationGroup *group = new QParallelAnimationGroup(child);

    QPoint point(0, 40);
    QPoint point2(0, height());
    QRect rcStart, rcEnd;
    rcEnd = QRect(point, QSize(width(), height() - 40));
    rcStart = QRect(point2, QSize(width(), 0));

    QPropertyAnimation *animation = new QPropertyAnimation(child, "geometry");
    animation->setDuration(180);
    animation->setStartValue(rcStart);
    animation->setEndValue(rcEnd);

    group->addAnimation(animation);

//    animation = new QPropertyAnimation(child, "opacity");
//    animation->setDuration(180);
//    group->addAnimation(animation);
    group->start(QAbstractAnimation::DeleteWhenStopped);

    m_bShowChild = true;
    UpdateCtrlState();
}

void MainPane::HideChild()
{
    BaseChildPane *child = GetChild();
    child->ClosePage();

    QPoint point(0, 40);
    QPoint point2(0, height());
    QRect rcStart, rcEnd;
    rcStart = QRect(point, QSize(width(), height() - 40));
    rcEnd = QRect(point2, QSize(width(), 0));

    QPropertyAnimation *animation = new QPropertyAnimation(child, "geometry");
    connect(animation, &QPropertyAnimation::finished, [=]() {
       child->hide();
    });
    animation->setDuration(180);
    animation->setStartValue(rcStart);
    animation->setEndValue(rcEnd);
    animation->start(QAbstractAnimation::DeleteWhenStopped);

    m_bShowChild = false;
    UpdateCtrlState();
}

BaseChildPane *MainPane::GetChild()
{
    QList<BaseChildPane *> listChilds = this->findChildren<BaseChildPane *>();
    foreach (BaseChildPane *child, listChilds) {
        if (child && child->isVisible())
            return child;
    }
    return nullptr;
}

QString MainPane::GetTitle()
{
    BaseChildPane *child = GetChild();
    if (child)
        return child->GetTitle();

    return "";
}

void MainPane::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    int rotate = this->property("rotate").toInt();
    if (m_pixFlash && rotate >= 0)
    {
        QSize sizeImg(470, 320);
        QPoint topleft((width() - 470) / 2, 0);
        QRect rcImg(topleft, sizeImg);
        painter.drawPixmap(rcImg, m_pixFlash->copy(rotate * 470, 0, 470, 320));
    }

    if (m_bShowChild)
    {
        painter.save();
        painter.setBrush(Qt::NoBrush);
        painter.setPen(QColor("#282828"));
        QFont font = painter.font();
        font.setPixelSize(16);
        painter.setFont(font);
        painter.drawText(QRect(0, 0, width(), 40), Qt::AlignCenter, GetTitle());
        painter.restore();
    }
}

QPushButton *CreateBtn(QString title, QString img)
{
    QPushButton *btn = new QPushButton();
    btn->setStyleSheet(QString("QWidget{border-style:none;"
                       "font-size: 16px;}"
                       "QWidget:hover{color: #ffa924;}"
                       "QPushButton{border-style:none;"
                       "text-align: center;"
                       "background-image: url(%1);"
                       "background-repeat: no-repeat}"
                       "QPushButton:hover{margin-left:-80px;}"
                       "QPushButton:pressed{margin-left:-160px;color: #ffa924;}").arg(img));
    btn->setFixedSize(80, 110);
    btn->setCursor(Qt::PointingHandCursor);

    QVBoxLayout *btnLayout = new QVBoxLayout(btn);
    btnLayout->setContentsMargins(0, 60, 0, 0);
    btnLayout->setSpacing(0);
    btnLayout->addStretch();
    QLabel *label = new QLabel(title, btn);
    label->setAlignment(Qt::AlignCenter);
    btnLayout->addWidget(label);


    QStateMachine *shadowStateMachine = new QStateMachine(btn);
    QState *normalState      = new QState;
    QState *hoverState       = new QState;
    QState *pressedState     = new QState;

    shadowStateMachine->addState(normalState);
    shadowStateMachine->addState(pressedState);

    normalState->assignProperty(label, "styleSheet", "color: #444444;");
    hoverState->assignProperty(label, "styleSheet", "color: #ffa924;");
    pressedState->assignProperty(label, "styleSheet", "color: #f17f05;");

    QAbstractTransition *transition;

    transition = new QEventTransition(btn, QEvent::MouseButtonPress);
    transition->setTargetState(pressedState);
    normalState->addTransition(transition);

    transition = new QEventTransition(btn, QEvent::MouseButtonDblClick);
    transition->setTargetState(pressedState);
    normalState->addTransition(transition);

    transition = new QEventTransition(btn, QEvent::Enter);
    transition->setTargetState(pressedState);
    normalState->addTransition(transition);

    transition = new QEventTransition(btn, QEvent::Leave);
    transition->setTargetState(normalState);
    pressedState->addTransition(transition);

    transition = new QEventTransition(btn, QEvent::MouseButtonRelease);
    transition->setTargetState(pressedState);
    pressedState->addTransition(transition);

    shadowStateMachine->setInitialState(normalState);
    shadowStateMachine->start();

    return btn;
}

QPushButton *CreateMiniBtn(QString title, QString img, QSize size, Function&& fn)
{
    QPushButton *btn = new QPushButton();
    btn->setStyleSheet(QString("QWidget{border-style:none;"
                       "font-size: 16px;}"
                       "QWidget:hover{color: #ffa924;}"
                       "QPushButton{border-style:none;"
                       "text-align: center;"
                       "background-image: url(%1);"
                       "background-repeat: no-repeat}"
                       "QPushButton:hover{margin-left:-%2px;}"
                       "QPushButton:pressed{margin-left:-%3px;color: #ffa924;}").arg(img).arg(size.width()).arg(size.width() * 2));
    btn->setFixedSize(size);
    btn->setToolTip(title);
    btn->setCursor(Qt::PointingHandCursor);

    QObject::connect(btn, &QPushButton::clicked, [=]() {
        if(fn) fn();
    });

    return btn;
}
